home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 2000 #4
/
Amiga Plus CD - 2000 - No. 4.iso
/
Tools
/
Emulatoren
/
UAE0.6.4
/
src
/
svga.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-05-27
|
14KB
|
548 lines
/*
* UAE - The Un*x Amiga Emulator
*
* SVGAlib interface.
*
* (c) 1995 Bernd Schmidt
*/
#include "sysconfig.h"
#include "sysdeps.h"
#include <assert.h>
#include <ctype.h>
#include <signal.h>
#include <vga.h>
#include <vgamouse.h>
#include <vgakeyboard.h>
#include "config.h"
#include "options.h"
#include "memory.h"
#include "custom.h"
#include "newcpu.h"
#include "keyboard.h"
#include "xwin.h"
#include "keybuf.h"
#include "gui.h"
#define SCODE_CURSORBLOCKUP 103 /* Cursor key block. */
#define SCODE_CURSORBLOCKLEFT 105
#define SCODE_CURSORBLOCKRIGHT 106
#define SCODE_CURSORBLOCKDOWN 108
#define SCODE_INSERT 110
#define SCODE_HOME 102
#define SCODE_PGUP 104
#define SCODE_DELETE 111
#define SCODE_END 107
#define SCODE_PGDN 109
#define SCODE_KEYPAD0 82
#define SCODE_KEYPAD1 79
#define SCODE_KEYPAD2 80
#define SCODE_KEYPAD3 81
#define SCODE_KEYPAD4 75
#define SCODE_KEYPAD5 76
#define SCODE_KEYPAD6 77
#define SCODE_KEYPAD7 71
#define SCODE_KEYPAD8 72
#define SCODE_KEYPAD9 73
#define SCODE_KEYPADENTER 96
#define SCODE_KEYPADPLUS 78
#define SCODE_KEYPADMINUS 74
#define SCODE_Q 16
#define SCODE_W 17
#define SCODE_E 18
#define SCODE_R 19
#define SCODE_T 20
#define SCODE_Y 21
#define SCODE_U 22
#define SCODE_I 23
#define SCODE_O 24
#define SCODE_P 25
#define SCODE_A 30
#define SCODE_S 31
#define SCODE_D 32
#define SCODE_F 33
#define SCODE_G 34
#define SCODE_H 35
#define SCODE_J 36
#define SCODE_K 37
#define SCODE_L 38
#define SCODE_Z 44
#define SCODE_X 45
#define SCODE_C 46
#define SCODE_V 47
#define SCODE_B 48
#define SCODE_N 49
#define SCODE_M 50
#define SCODE_ESCAPE 1
#define SCODE_ENTER 28
#define SCODE_RIGHTCONTROL 97
#define SCODE_CONTROL 97
#define SCODE_RIGHTALT 100
#define SCODE_LEFTCONTROL 29
#define SCODE_LEFTALT 56
#define SCODE_SPACE 57
#define SCODE_F1 59
#define SCODE_F2 60
#define SCODE_F3 61
#define SCODE_F4 62
#define SCODE_F5 63
#define SCODE_F6 64
#define SCODE_F7 65
#define SCODE_F8 66
#define SCODE_F9 67
#define SCODE_F10 68
#define SCODE_0 11
#define SCODE_1 2
#define SCODE_2 3
#define SCODE_3 4
#define SCODE_4 5
#define SCODE_5 6
#define SCODE_6 7
#define SCODE_7 8
#define SCODE_8 9
#define SCODE_9 10
#define SCODE_LEFTSHIFT 42
#define SCODE_RIGHTSHIFT 54
#define SCODE_TAB 15
#define SCODE_F11 87
#define SCODE_F12 88
#define SCODE_NEXT 81
#define SCODE_PRIOR 73
#define SCODE_BS 14
/*
#define SCODE_asciicircum 1
*/
#define SCODE_bracketleft 26
#define SCODE_bracketright 27
#define SCODE_comma 51
#define SCODE_period 52
#define SCODE_slash 53
#define SCODE_semicolon 39
#define SCODE_grave 40
#define SCODE_minus 12
#define SCODE_equal 13
#define SCODE_numbersign 43
#define SCODE_ltgt 86
#define SCODE_scrolllock 70
#define SCODE_LWIN95 125
#define SCODE_RWIN95 126
#define SCODE_MWIN95 127
void setup_brkhandler(void)
{
}
static int vsize, bitdepth, bit_unit, using_linear;
static vga_modeinfo modeinfo;
static char *linear_mem = NULL;
static int need_dither;
static int x_size = 0, vidmode_linewidth;
static UBYTE dither_buf[1000]; /* I hate having to think about array bounds */
xcolnr xcolors[4096];
struct vidbuf_description gfxvidinfo;
static int x_size_table[MAX_SCREEN_MODES+1] = { 320, 320, 320, 640, 800 };
static int vga_mode_table[MAX_SCREEN_MODES+1][MAX_COLOR_MODES+1] =
{ { G320x200x256, G320x200x32K, G320x200x64K, G320x200x256, G320x200x16, G320x200x16M32 },
{ G320x240x256, -1, -1, G320x240x256, -1, -1 },
{ G320x400x256, -1, -1, G320x400x256, -1, -1 },
{ G640x480x256, G640x480x32K, G640x480x64K, G640x480x256, G640x480x16, G640x480x16M32 },
{ G800x600x256, G800x600x32K, G800x600x64K, G800x600x256, G800x600x16, G800x600x16M32 } };
static int mode_bitdepth[MAX_COLOR_MODES+1][3] =
{ { 8, 8, 0 }, { 15, 16, 0 }, { 16, 16, 0 }, { 8, 8, 1 }, { 4, 8, 1 }, { 24, 32, 0 } };
void flush_line(int y)
{
int target_y = y;
if (screen_res < 2)
target_y -= 8;
if (linear_mem == NULL) {
char *addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
if (target_y < modeinfo.height && target_y >= 0) {
if (need_dither) {
DitherLine(dither_buf, (UWORD *)addr, 0, y, x_size, bit_unit);
addr = dither_buf;
}
vga_drawscanline(target_y, addr);
}
} else {
if (need_dither && target_y >= 0) {
char *addr = gfxvidinfo.bufmem + y*gfxvidinfo.rowbytes;
DitherLine(linear_mem + vidmode_linewidth * target_y, (UWORD *)addr, 0, y, x_size, bit_unit);
}
}
}
void flush_block(int a, int b)
{
abort();
}
void flush_screen(int a, int b)
{
}
void calc_adjustment(void)
{
switch (screen_res) {
case 0: case 1: case 2: /* LoRes, 320xfoo */
gfxvidinfo.x_adjust = prev_max_diwstop - 320;
break;
case 3: /* 640xbar */
gfxvidinfo.x_adjust = prev_max_diwstop - 640;
break;
default:
gfxvidinfo.x_adjust = 0;
break;
}
}
static int colors_allocated;
static int get_color(int r, int g, int b, xcolnr *cnp)
{
if (colors_allocated == 256)
return -1;
*cnp = colors_allocated;
vga_setpalette(colors_allocated, doMask(r, 6, 0), doMask(g, 6, 0), doMask(b, 6, 0));
colors_allocated++;
return 1;
}
static void init_colors(void)
{
if (need_dither) {
setup_dither(bitdepth, get_color);
} else {
int rw = 5, gw = 5, bw = 5;
colors_allocated = 0;
if (color_mode == 2) gw = 6;
switch (gfxvidinfo.pixbytes) {
case 4:
alloc_colors64k(8, 8, 8, 16, 8, 0);
break;
case 2:
alloc_colors64k(rw, gw, bw, gw+bw, bw, 0);
break;
case 1:
alloc_colors256(get_color);
break;
default:
abort();
}
}
}
int buttonstate[3] = { 0, 0, 0 };
int lastmx, lastmy;
int newmousecounters = 0;
static int keystate[256];
static int scancode2amiga(int scancode)
{
switch(scancode) {
case SCODE_A: return AK_A;
case SCODE_B: return AK_B;
case SCODE_C: return AK_C;
case SCODE_D: return AK_D;
case SCODE_E: return AK_E;
case SCODE_F: return AK_F;
case SCODE_G: return AK_G;
case SCODE_H: return AK_H;
case SCODE_I: return AK_I;
case SCODE_J: return AK_J;
case SCODE_K: return AK_K;
case SCODE_L: return AK_L;
case SCODE_M: return AK_M;
case SCODE_N: return AK_N;
case SCODE_O: return AK_O;
case SCODE_P: return AK_P;
case SCODE_Q: return AK_Q;
case SCODE_R: return AK_R;
case SCODE_S: return AK_S;
case SCODE_T: return AK_T;
case SCODE_U: return AK_U;
case SCODE_V: return AK_V;
case SCODE_W: return AK_W;
case SCODE_X: return AK_X;
case SCODE_Y: return AK_Y;
case SCODE_Z: return AK_Z;
case SCODE_0: return AK_0;
case SCODE_1: return AK_1;
case SCODE_2: return AK_2;
case SCODE_3: return AK_3;
case SCODE_4: return AK_4;
case SCODE_5: return AK_5;
case SCODE_6: return AK_6;
case SCODE_7: return AK_7;
case SCODE_8: return AK_8;
case SCODE_9: return AK_9;
case SCODE_KEYPAD0: return AK_NP0;
case SCODE_KEYPAD1: return AK_NP1;
case SCODE_KEYPAD2: return AK_NP2;
case SCODE_KEYPAD3: return AK_NP3;
case SCODE_KEYPAD4: return AK_NP4;
case SCODE_KEYPAD5: return AK_NP5;
case SCODE_KEYPAD6: return AK_NP6;
case SCODE_KEYPAD7: return AK_NP7;
case SCODE_KEYPAD8: return AK_NP8;
case SCODE_KEYPAD9: return AK_NP9;
case SCODE_F1: return AK_F1;
case SCODE_F2: return AK_F2;
case SCODE_F3: return AK_F3;
case SCODE_F4: return AK_F4;
case SCODE_F5: return AK_F5;
case SCODE_F6: return AK_F6;
case SCODE_F7: return AK_F7;
case SCODE_F8: return AK_F8;
case SCODE_F9: return AK_F9;
case SCODE_F10: return AK_F10;
case SCODE_BS: return AK_BS;
case SCODE_LEFTCONTROL: return AK_CTRL;
case SCODE_RIGHTCONTROL: return AK_CTRL;
case SCODE_TAB: return AK_TAB;
case SCODE_LEFTALT: return AK_LALT;
case SCODE_RIGHTALT: return AK_RALT;
case SCODE_ENTER: return AK_RET;
case SCODE_SPACE: return AK_SPC;
case SCODE_LEFTSHIFT: return AK_LSH;
case SCODE_RIGHTSHIFT: return AK_RSH;
case SCODE_ESCAPE: return AK_ESC;
case SCODE_INSERT:
case SCODE_END:
case SCODE_HOME: break;
case SCODE_DELETE: return AK_DEL;
case SCODE_CURSORBLOCKUP: return AK_UP;
case SCODE_CURSORBLOCKDOWN: return AK_DN;
case SCODE_CURSORBLOCKLEFT: return AK_LF;
case SCODE_CURSORBLOCKRIGHT: return AK_RT;
case SCODE_F11: return AK_BACKSLASH;
/*
case SCODE_asciicircum: return AK_00;
*/
case SCODE_bracketleft: return AK_LBRACKET;
case SCODE_bracketright: return AK_RBRACKET;
case SCODE_comma: return AK_COMMA;
case SCODE_period: return AK_PERIOD;
case SCODE_slash: return AK_SLASH;
case SCODE_semicolon: return AK_SEMICOLON;
case SCODE_grave: return AK_QUOTE;
case SCODE_minus: return AK_MINUS;
case SCODE_equal: return AK_EQUAL;
/* This one turns off screen updates. */
case SCODE_scrolllock: return AK_inhibit;
case SCODE_PGUP: case SCODE_RWIN95: return AK_RAMI;
case SCODE_PGDN: case SCODE_LWIN95: return AK_LAMI;
/*#ifdef KBD_LANG_DE*/
case SCODE_numbersign: return AK_NUMBERSIGN;
case SCODE_ltgt: return AK_LTGT;
/*#endif*/
}
return -1;
}
static void my_kbd_handler(int scancode, int newstate)
{
int akey = scancode2amiga(scancode);
assert(scancode >= 0 && scancode < 0x100);
if (scancode == SCODE_F12) {
regs.spcflags |= SPCFLAG_BRK;
quit_program = 1;
}
if (keystate[scancode] == newstate)
return;
keystate[scancode] = newstate;
if (akey == -1) {
return;
}
if (newstate == KEY_EVENTPRESS) {
if (akey == AK_inhibit)
inhibit_frame ^= 1;
else
record_key (akey << 1);
} else
record_key ((akey << 1) | 1);
/* "Affengriff" */
if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
m68k_reset();
}
int graphics_init(void)
{
int i;
int vgamode;
need_dither = 0;
using_linear = 0;
if (screen_res < 3)
correct_aspect = 0;
vgamode = vga_mode_table[screen_res][color_mode];
if (vgamode == -1) {
fprintf(stderr, "Sorry, this combination of color and video mode is not supported.\n");
return 0;
}
bitdepth = mode_bitdepth[color_mode][0];
bit_unit = mode_bitdepth[color_mode][1];
need_dither = mode_bitdepth[color_mode][2];
x_size = x_size_table[screen_res];
vga_init();
modeinfo = *vga_getmodeinfo (vgamode);
vidmode_linewidth = modeinfo.linewidth;
gfxvidinfo.pixbytes = modeinfo.bytesperpixel;
if (!need_dither) {
if (modeinfo.bytesperpixel == 0) {
printf("Got a bogus value from SVGAlib... %s.\n",
screen_res == 1 || screen_res == 2 ? "trying to fix it" : "giving up");
if (screen_res != 1 && screen_res != 2)
return 0;
gfxvidinfo.pixbytes = 1;
}
} else {
gfxvidinfo.pixbytes = 2;
}
if (vga_setmode(vgamode) < 0) {
sleep(1);
vga_setmode(TEXT);
fprintf(stderr, "SVGAlib doesn't like my video mode. Giving up.\n");
return 0;
}
if ((modeinfo.flags & CAPABLE_LINEAR) && !no_xhair) {
if (vga_setlinearaddressing() != -1) {
linear_mem = (char *)vga_getgraphmem();
printf("Using linear addressing: %p.\n", linear_mem);
using_linear = !need_dither;
}
}
vsize = correct_aspect ? 2*numscrlines : numscrlines;
gfxvidinfo.maxblocklines = 0;
if (using_linear) {
gfxvidinfo.bufmem = linear_mem;
gfxvidinfo.rowbytes = modeinfo.linewidth;
} else {
gfxvidinfo.rowbytes = x_size * gfxvidinfo.pixbytes;
gfxvidinfo.bufmem = malloc(gfxvidinfo.rowbytes * vsize);
memset(gfxvidinfo.bufmem, 0, gfxvidinfo.rowbytes * vsize);
}
gfxvidinfo.maxlinetoscr = x_size < 800 ? x_size : 0;
gfxvidinfo.x_adjust = 0;
gfxvidinfo.maxline = modeinfo.height;
init_colors();
vga_setmousesupport(1);
mouse_init("/dev/mouse",vga_getmousetype(),10);
if (keyboard_init() != 0)
abort();
keyboard_seteventhandler(my_kbd_handler);
keyboard_translatekeys(DONT_CATCH_CTRLC);
buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
for(i = 0; i < 256; i++)
keystate[i] = 0;
lastmx = lastmy = 0;
newmousecounters = 0;
mouse_setxrange(-1000,1000);
mouse_setyrange(-1000,1000);
mouse_setposition(0,0);
return 1;
}
void graphics_leave(void)
{
sleep(1); /* Maybe this will fix the "screen full of garbage" problem */
vga_setmode(TEXT);
keyboard_close();
dumpcustom();
}
void handle_events(void)
{
int button = mouse_getbutton();
keyboard_update();
mouse_update();
lastmx += mouse_getx();
lastmy += mouse_gety();
mouse_setposition(0,0);
buttonstate[0] = button & 4;
buttonstate[1] = button & 2;
buttonstate[2] = button & 1;
}
int debuggable(void)
{
return 0;
}
int needmousehack(void)
{
return 0;
}
void LED(int on)
{
}
void target_specific_usage(void)
{
printf(" -S n : Sound emulation accuracy (n = 0, 1, 2 or 3)\n"
" For sound emulation, n = 2 is recommended\n");
printf(" -b n : Use n bits for sound output (8 or 16)\n");
printf(" -R n : Use n Hz to output sound. Common values are\n"
" 22050 Hz or 44100 Hz\n");
printf(" -B n : Use a sound buffer of n bytes (use small\n"
" values on fast machines)\n");
printf(" -x : Don't use SVGAlib linear framebuffer, even if available.\n");
printf(" -p command : Use command to pipe printer output to.\n");
printf(" -I device : Name of the used serial device (i.e. /dev/ttyS1\n");
}